package com.example.villagemanager.util.bluetooth;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.example.villagemanager.config.Constant;
import com.example.villagemanager.listener.OnDeviceSearchListener;
import com.example.villagemanager.model.event.Event;
import com.example.villagemanager.util.bluetooth.thread.ConnectThread;
import com.example.villagemanager.util.bluetooth.thread.ConnectedThread;

import org.greenrobot.eventbus.EventBus;

import androidx.annotation.NonNull;

import static com.example.villagemanager.util.bluetooth.thread.ConnectedThread.bytes2HexString;


public class BlueToothUtil {
    private static BlueToothUtil blueToothUtil;
    protected static final String TAG = "BlueToothUtil";
    private  Context context;
    public  BluetoothAdapter btAdapter;
    public  BtBroadcastReceiver btBroadcastReceiver;
    public ConnectThread connectThread;
    private ConnectedThread connectedThread;
    Handler mHandler=new Handler(){
        @Override
        public void dispatchMessage(@NonNull Message msg) {
            super.dispatchMessage(msg);
        }
    };
    private boolean curConnState;

    public static BlueToothUtil init(Context context) {
        if (blueToothUtil==null){
            blueToothUtil=new BlueToothUtil();
        }
        blueToothUtil.context=context;
        return blueToothUtil;
    }

    public void unregisterReceiver() {
        context.unregisterReceiver(btBroadcastReceiver);
    }

    /**
     * 蓝牙广播接收器
     */
    private static class BtBroadcastReceiver extends BroadcastReceiver {
        private  OnDeviceSearchListener onDeviceSearchListener;
        @SuppressLint("MissingPermission")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (TextUtils.equals(action, BluetoothAdapter.ACTION_DISCOVERY_STARTED)) { //开启搜索
                if (onDeviceSearchListener != null) {
                    onDeviceSearchListener.onDiscoveryStart();  //开启搜索回调
                }

            } else if (TextUtils.equals(action, BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {//完成搜素
                if (onDeviceSearchListener != null) {
                    onDeviceSearchListener.onDiscoveryStop();
                    EventBus.getDefault().post(new Event(Constant.BLUE_TOOTH_SCAN_FINISH_CODE));//完成搜素回调
                }

            } else if (TextUtils.equals(action, BluetoothDevice.ACTION_FOUND)) {  //3.0搜索到设备
                //蓝牙设备
                BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                //信号强度
                int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);


                if (onDeviceSearchListener != null) {
                    onDeviceSearchListener.onDeviceFound(bluetoothDevice,rssi);  //3.0搜素到设备回调
                }
                EventBus.getDefault().post(new Event(Constant.BLUE_TOOTH_SCAN_FINDED_CODE,bluetoothDevice));
            }
        }

        /**
         * 蓝牙设备搜索监听者
         * 1、开启搜索
         * 2、完成搜索
         * 3、搜索到设备
         */




        public void setOnDeviceSearchListener(OnDeviceSearchListener onDeviceSearchListener) {
            this.onDeviceSearchListener = onDeviceSearchListener;
        }
    }

    @SuppressLint("MissingPermission")
    public  void searchBtDevice() {
        if(btAdapter.isDiscovering()){ //当前正在搜索设备...
            return;
        }
        //开始搜索
        btAdapter.startDiscovery();
    }


    public   void initBtBroadcast(OnDeviceSearchListener listener) {
        //注册广播接收
        btBroadcastReceiver = new BtBroadcastReceiver();
        btBroadcastReceiver.setOnDeviceSearchListener(listener);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); //开始扫描
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//扫描结束
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);//搜索到设备
        context.registerReceiver(btBroadcastReceiver,intentFilter);

    }
    @SuppressLint("MissingPermission")
    public  void initBluetooth() {
        btAdapter= BluetoothAdapter.getDefaultAdapter();
        if(btAdapter == null){
            Toast.makeText(context, "当前手机设备不支持蓝牙", Toast.LENGTH_SHORT).show();
        }else{
            //手机设备支持蓝牙，判断蓝牙是否已开启
            if(btAdapter.isEnabled()){
                Toast.makeText(context, "手机蓝牙已开启", Toast.LENGTH_SHORT).show();
            }else{
                //蓝牙没有打开，去打开蓝牙。推荐使用第二种打开蓝牙方式
                //第一种方式：直接打开手机蓝牙，没有任何提示
                btAdapter.enable();  //BLUETOOTH_ADMIN权限
                //第二种方式：友好提示用户打开蓝牙
//                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//                context.startActivity(enableBtIntent);
            }
        }
    }

    public void startConnectDevice(final BluetoothDevice bluetoothDevice, String uuid, long conOutTime){
        if(bluetoothDevice == null){
            Log.e(TAG,"startConnectDevice-->bluetoothDevice == null");
            return;
        }
        if(btAdapter == null){
            Log.e(TAG,"startConnectDevice-->bluetooth3Adapter == null");
            return;
        }
        //发起连接
        connectThread = new ConnectThread(btAdapter,bluetoothDevice,uuid);
        connectThread.setOnBluetoothConnectListener(new ConnectThread.OnBluetoothConnectListener() {
            @SuppressLint("MissingPermission")
            @Override
            public void onStartConn() {
                Log.d(TAG,"startConnectDevice-->开始连接..." + bluetoothDevice.getName() + "-->" + bluetoothDevice.getAddress());
            }


            @Override
            public void onConnSuccess(BluetoothSocket bluetoothSocket) {
                //移除连接超时
                mHandler.removeCallbacks(connectOuttimeRunnable);
                Log.d(TAG,"startConnectDevice-->移除连接超时");
                Log.w(TAG,"startConnectDevice-->连接成功");

                Message message = new Message();
                message.what = Constant.BLUE_TOOTH_CONNECT_SUCCESS_CODE;
                mHandler.sendMessage(message);

                //标记当前连接状态为true
                curConnState = true;
                //管理连接，收发数据
                managerConnectSendReceiveData(bluetoothSocket);
            }

            @Override
            public void onConnFailure(String errorMsg) {
                Log.e(TAG,"startConnectDevice-->" + errorMsg);

                Message message = new Message();
                message.what  = Constant.BLUE_TOOTH_CONNECT_FAILURE_CODE;
                mHandler.sendMessage(message);

                //标记当前连接状态为false
                curConnState = false;

                //断开管理连接
                clearConnectedThread();
            }
        });

        connectThread.start();
        //设置连接超时时间
        mHandler.postDelayed(connectOuttimeRunnable,conOutTime);

    }

    //连接超时
    private Runnable connectOuttimeRunnable = new Runnable() {
        @Override
        public void run() {
            Log.e(TAG,"startConnectDevice-->连接超时" );

            Message message = new Message();
            message.what = Constant.BLUE_TOOTH_CONNECT_FAILURE_CODE;
            mHandler.sendMessage(message);

            //标记当前连接状态为false
            curConnState = false;
            //断开管理连接
            clearConnectedThread();
        }
    };
    /**
     * 断开已有的连接
     */
    public void clearConnectedThread(){
        Log.d(TAG,"clearConnectedThread-->即将断开");

        //connectedThread断开已有连接
        if(connectedThread == null){
            Log.e(TAG,"clearConnectedThread-->connectedThread == null");
            return;
        }
        connectedThread.terminalClose(connectThread);

        //等待线程运行完后再断开
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                connectedThread.cancel();  //释放连接

                connectedThread = null;
            }
        },10);

        Log.w(TAG,"clearConnectedThread-->成功断开连接");
        Message message = new Message();
        message.what = Constant.BLUE_TOOTH_DISCONNECT_SUCCESS_CODE;
        mHandler.sendMessage(message);

    }

    /**
     * 管理已建立的连接，收发数据
     * @param bluetoothSocket   已建立的连接
     */
    public void managerConnectSendReceiveData(BluetoothSocket bluetoothSocket){
        //管理已有连接
        connectedThread = new ConnectedThread(bluetoothSocket);
        connectedThread.start();
        connectedThread.setOnSendReceiveDataListener(new ConnectedThread.OnSendReceiveDataListener() {
            @Override
            public void onSendDataSuccess(byte[] data) {
                Log.w(TAG,"发送数据成功,长度" + data.length + "->" + bytes2HexString(data,data.length));
                Message message = new Message();
                message.what = Constant.BLUE_TOOTH_SEND_SUCCESS_CODE;
                message.obj = "发送数据成功,长度" + data.length + "->" + bytes2HexString(data,data.length);
                mHandler.sendMessage(message);
            }

            @Override
            public void onSendDataError(byte[] data,String errorMsg) {
                Log.e(TAG,"发送数据出错,长度" + data.length + "->" + bytes2HexString(data,data.length));
                Message message = new Message();
                message.what = Constant.BLUE_TOOTH_SEND_FAILURE_CODE;
                message.obj = "发送数据出错,长度" + data.length + "->" + bytes2HexString(data,data.length);
                mHandler.sendMessage(message);
            }

            @Override
            public void onReceiveDataSuccess(byte[] buffer) {
                Log.w(TAG,"成功接收数据,长度" + buffer.length + "->" + bytes2HexString(buffer,buffer.length));
                Message message = new Message();
                message.what = Constant.BLUE_TOOTH_RECEIVE_SUCCESS_CODE;
                message.obj = "成功接收数据,长度" + buffer.length + "->" + bytes2HexString(buffer,buffer.length);
                mHandler.sendMessage(message);
            }

            @Override
            public void onReceiveDataError(String errorMsg) {
                Log.e(TAG,"接收数据出错：" + errorMsg);
                Message message = new Message();
                message.what = Constant.BLUE_TOOTH_RECEIVE_FAILURE_CODE;
                message.obj = "接收数据出错：" + errorMsg;
                mHandler.sendMessage(message);
            }
        });
    }
}
